/*
 * @Author       : Bing Chen chenbing@iocharger.com
 * @Date         : 2024-05-20 22:37:40
 * @LastEditors  : Bing Chen chenbing@iocharger.com
 * @LastEditTime : 2025-03-15 12:47:18
 * @FilePath     : \openchaoji-corelib\secc\app\OpenChaoJi_secc_main.c
 * @Description  : secc的主入口
 *
 * Copyright (c) 2025 OpenChaoJi
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the icense for the specific language governing permissions and
 * limitations under the License.
 *
 */

#include "OpenChaoJi_secc.h"

#ifndef DEMO_APP_FOR_GCC
//struct OpenChaoJi_secc_context * context_a = NULL;
struct OpenChaoJi_secc_context * context_b = NULL;

int main()
{
    // 厂家首先需要初始化HAL层
//    OpenChaoJi_hal_handle hal_handle_a = NULL;
    OpenChaoJi_hal_handle hal_handle_b = NULL;//(OpenChaoJi_hal_handle)&CNST_OpenChaoJi01;
	// OpenChaoJi_secc_hal_init(hal_handle_b);
	// OpenChaoJi_InstallShell();


    // 创建上下文, 上下文将是后续所有模块通信的唯一句柄
//    struct OpenChaoJi_secc_context_create_info info_a;
//    info_a.secc_gbt27930_type = OPENCHAOJI_SECC_GBT27930_TYPE_A;
//    info_a.hal_handle = hal_handle_a;
//    context_a = OpenChaoJi_secc_create_context(&info_a);

    struct OpenChaoJi_secc_context_create_info info_b;
	info_b.tag = 0;
	info_b.hal_handle = hal_handle_b;
    info_b.secc_gbt27930_type = OPENCHAOJI_SECC_GBT27930_TYPE_B;

	info_b.pilot.secc_gbt27930_type = OPENCHAOJI_SECC_GBT27930_TYPE_B;
	info_b.pilot.hal_handle = hal_handle_b;

	info_b.session.hal_handle = hal_handle_b;
	info_b.session.secc_gbt27930_type = OPENCHAOJI_SECC_GBT27930_TYPE_B;	// 初始化协议类型，OpenChaoJi_secc_create_context形参有const修饰，外部初始化

	info_b.session.data_buff.recv_capacity = 4;

	info_b.session.linkage.gbt27930_info.gbt27930_b.can_type	 = OPENCHAOJI_GBT27930_B_CAN_TYPE_20;
    info_b.session.linkage.gbt27930_info.gbt27930_b.secc_version = OPENCHAOJI_GBT27930_B_PROTOCOL_VERSION_TYPE_2_0_0;
    info_b.session.linkage.tag = 0;
    info_b.session.linkage.hal_handle = hal_handle_b;
    info_b.session.linkage.secc_gbt27930_type = OPENCHAOJI_SECC_GBT27930_TYPE_B;

    context_b = OpenChaoJi_secc_create_context(&info_b);

    // 通过定时触发service服务来驱动整个系统的活动
    // 厂家可以通过线程,中断,死循环等各种方式实现, 只需要保证频度足够
    // 但是本方法需要保证不能阻塞
    while (1)
    {
//        OpenChaoJi_secc_service(context_a);
        OpenChaoJi_secc_service(context_b);

		OpenChaoJi_secc_utility_session_service(context_b->context_session);

        // OpenChaoJi_secc_app_get_status(context_b, );
        if  (status == end || status == fault)
        {
            OpenChaoJi_secc_app_stop(context_b);
        }


//        usleep(10000);
		Djy_EventDelay( 5*mS );
    }

//	OpenChaoJi_secc_destroy_context(context_a);
	OpenChaoJi_secc_destroy_context(context_b);


    return 0;
}


void interrupt_emergency_a()
{
    OpenChaoJi_secc_service(context_a);
}

void interrupt_emergency_b()
{
    OpenChaoJi_secc_service(context_b);
}

#else

// 基于标准Linux的测试系统
#include <unistd.h>

extern void secc_app_init();
extern void secc_app_service();
extern void secc_app_term();

int main()
{
    secc_app_init();

    // 通过定时触发service服务来驱动整个系统的活动
    // 厂家可以通过线程,中断,死循环等各种方式实现, 只需要保证频度足够
    // 但是本方法需要保证不能阻塞
    while (1)
    {
        secc_app_service();

        usleep(2000);
    }

    secc_app_term();

    return 0;
}


#endif

enum secc_app_auth_status OpenChaoJi_secc_app_check_auth_rfid(struct OpenChaoJi_secc_context * context)
{
    static uint32_t s_start_check_rfid = 0;
    if (s_start_check_rfid == 0)
    {
        s_start_check_rfid = OpenChaoJi_os_get_ticks();
        return SECC_APP_AUTH_STATUS_CHECKING;
    }

    if (OpenChaoJi_os_get_ticks() > (s_start_check_rfid + 3000))
    {
        s_start_check_rfid = 0;
        return SECC_APP_AUTH_STATUS_OK;
    }

    return SECC_APP_AUTH_STATUS_CHECKING;
}

enum secc_app_auth_status OpenChaoJi_secc_app_check_auth_evin(struct OpenChaoJi_secc_context * context, uint8_t evin[17])
{
    static uint32_t s_start_check_evin = 0;
    if (s_start_check_evin == 0)
    {
        s_start_check_evin = OpenChaoJi_os_get_ticks();
        return SECC_APP_AUTH_STATUS_CHECKING;
    }

    if (OpenChaoJi_os_get_ticks() > (s_start_check_evin + 2000))
    {
        s_start_check_evin = 0;
        return SECC_APP_AUTH_STATUS_OK;
    }

    return SECC_APP_AUTH_STATUS_CHECKING;
}

// 向APP发送当前车辆需求充电电压电流, 要求App根据这个请求计算出实际应当发给充电模块的请求电压和电流
void OpenChaoJi_secc_app_get_power_output(struct OpenChaoJi_secc_context * context
        , const struct OpenChaoJi_secc_gbt27930_charging_requirement_parameter * evcc_requirement
        , unsigned int * volt_power_module, unsigned int * curr_power_module)
{
    *volt_power_module = evcc_requirement->voltage;
    *curr_power_module = evcc_requirement->current;

    return;
}

#if (OPENCHAOJI_CONFIG_ENABLE_GBT27930_B == CONFIG_YES)

// 向APP请求当前输出能力, APP需要跟上次的能力进行比较
// 如果发生变化了, 需要对 dynamic_output 赋值, 给出当前能力和变化原因, 并返回1
// 如果没有变化, 返回0
int OpenChaoJi_secc_app_check_dynamic_output(struct OpenChaoJi_secc_context * context
        , struct OpenChaoJi_gbt27930_b_msg_charging_ability_secc * dynamic_output)
{
    return 0;
}


// 充电结束时请求服务统计信息
void OpenChaoJi_secc_app_get_charge_total_energy(struct OpenChaoJi_secc_context * context
        , OpenChaoJi_gbt27930_b_CapcityType * charge_total_energy)
{
    *charge_total_energy = 100;

    return;
}
#endif

/******************************获取充电机设备信息******************************/

/**
 * @brief  获取充电机编号
 * @param  {OpenChaoJi_secc_context *} context 系统上下文指针
 * @return 充电机编号, 1/位, 0偏移量
 */
unsigned int OpenChaoJi_secc_app_get_charger_id(struct OpenChaoJi_secc_context * context)
{
    return 123;
}

/**
 * @brief  获取充电机/充电站所在区域编码（数组）
 * @param  {OpenChaoJi_secc_context *} context 系统上下文指针
 * @param  charger_location: 充电机/充电站所在区域编码, 3字节, 标准ASCII码, 低字节在前
 * @return void
 */
void OpenChaoJi_secc_app_get_charger_location(struct OpenChaoJi_secc_context * context, unsigned char *charger_location)
{
    char tmp[5] = "CN";
    memcpy(charger_location, tmp, 3);
    return;
}

/**
 * @brief  获取充电允许状态标识（充电暂停）
 * @param  {OpenChaoJi_secc_context *} context 系统上下文指针
 * @return 充电允许状态标识, 0x00:充电暂停, 0x01:充电允许
 */
unsigned char OpenChaoJi_secc_app_get_charger_enable(struct OpenChaoJi_secc_context * context)
{
    return 0x01;
}

/**
 * @brief  获取通信超时重连允许次数
 * @param  {OpenChaoJi_secc_context *} context 系统上下文指针
 * @return 允许重连次数
 */
unsigned int OpenChaoJi_secc_app_get_permit_reconnect_cnt(struct OpenChaoJi_secc_context * context)
{
    return 3;
}

/**
 * @brief  获取充电机累计充电时间（本次）
 * @param  {OpenChaoJi_secc_context *} context 系统上下文指针
 * @return 充电时间, 1min/位, 0min偏移量, 0-600min
 */
unsigned int OpenChaoJi_secc_app_get_charging_time(struct OpenChaoJi_secc_context * context)
{
    return 0;
}

/**
 * @brief  获取充电机充电输出能量
 * @param  {OpenChaoJi_secc_context *} context 系统上下文指针
 * @return 充电输出能量, 0.1kWh/位, 0kWh偏移量, 0-1000kWh
 */
unsigned int OpenChaoJi_secc_app_get_output_energy(struct OpenChaoJi_secc_context * context)
{
    return 0;
}

